package bomberman.modelo.mapa;

import java.util.HashMap;

import org.jdom2.Element;

import bomberman.modelo.IContenible;
import bomberman.modelo.IDaniable;
import bomberman.modelo.armas.Explosion;
import bomberman.modelo.armas.OndaExpansiva;
import bomberman.modelo.personajes.Personaje;

public class Casillero {
  private IContenible                   contenidoBajo;
  private IContenible                   contenidoMedio;
  private IContenible                   contenidoAlto;
  private HashMap<Direccion, Casillero> vecinos;
  private Posicion                      posicion;
  
  public Casillero(Posicion unaPosicion, IContenible unContenidoBajo, IContenible unContenidoMedio,
    IContenible unContenidoAlto) {
    this.vecinos = new HashMap<Direccion, Casillero>();
    this.posicion = unaPosicion;
    this.contenidoBajo = unContenidoBajo;
    this.contenidoMedio = unContenidoMedio;
    this.contenidoAlto = unContenidoAlto;
  }
  
  public void setVecino(Direccion direccion, Casillero vecino) {
    this.vecinos.put(direccion, vecino);
  }
  
  public void setContenidoBajo(IContenible unContenido) {
    this.contenidoBajo = unContenido;
  }
  
  public void setContenidoMedio(IContenible unContenido) {
    this.contenidoMedio = unContenido;
  }
  
  public void setContenidoAlto(IContenible unContenido) {
    this.contenidoAlto = unContenido;
  }
  
  public IContenible getContenidoBajo() {
    return this.contenidoBajo;
  }
  
  public IContenible getContenidoMedio() {
    return this.contenidoMedio;
  }
  
  public IContenible getContenidoAlto() {
    return this.contenidoAlto;
  }
  
  public HashMap<Direccion, Casillero> getVecinos() {
    return this.vecinos;
  }
  
  public Posicion getPosicion() {
    return this.posicion;
  }
  
  public void setPosicion(Posicion posicion) {
    this.posicion = posicion;
  }
  
  public boolean esCaminablePor(Personaje unPersonaje) {
    return ((this.contenidoBajo == null) || this.contenidoBajo.esCaminablePor(unPersonaje));
  }
  
  public boolean esSobrevolable() {
    return ((this.contenidoAlto == null) && ((this.contenidoBajo == null) || (this.contenidoBajo.esSobrevolable())));
  }
  
  public boolean esBalisticamentePermeable() {
    return ((this.contenidoBajo == null) || this.contenidoBajo.esBalisticamentePermeable())
      && ((this.contenidoMedio == null) || this.contenidoMedio.esBalisticamentePermeable())
      && ((this.contenidoAlto == null) || this.contenidoAlto.esBalisticamentePermeable());
  }
  
  private void avanzarOnda(OndaExpansiva ondaExpansiva) {
    ondaExpansiva.avanzar(1);
    if (ondaExpansiva.getRadio() > 0) {
      if (this.vecinos.containsKey(ondaExpansiva.getDireccion())) {
        this.vecinos.get(ondaExpansiva.getDireccion()).recibirImpacto(ondaExpansiva);
      }
    }
  }
  
  public void recibirImpacto(OndaExpansiva ondaExpansiva) {
    Explosion.explotar(this.posicion);
    if (this.contenidoBajo == null) {
      this.avanzarOnda(ondaExpansiva);
    } else
      if (this.contenidoBajo instanceof IDaniable) {
        ondaExpansiva.daniar((IDaniable) this.contenidoBajo);
      } else {
        this.avanzarOnda(ondaExpansiva);
      }
  }
  
  public Casillero getVecino(Direccion direccion) {
    return this.vecinos.get(direccion);
  }
  
  public void salgoCaminando(Personaje unPersonaje) {
    if (this.getContenidoBajo() == unPersonaje) {
      this.setContenidoBajo(null);
    }
  }
  
  public void salgoVolando(Personaje unPersonaje) {
    if (this.getContenidoAlto() == unPersonaje) {
      this.setContenidoAlto(null);
    }
  }
  
  public void entroCaminando(Personaje unPersonaje) {
    this.setContenidoBajo(unPersonaje);
  }
  
  public void entroVolando(Personaje unPersonaje) {
    this.setContenidoAlto(unPersonaje);
  }
  
  public Element serializarUbicacion() {
    Element eUbicacion = new Element("Ubicacion");
    eUbicacion.setAttribute("X", String.valueOf(this.getPosicion().getVertical()));
    eUbicacion.setAttribute("Y", String.valueOf(this.getPosicion().getHorizontal()));
    return eUbicacion;
  }
  
  public Element serializarContenidoBajo() {
    Element eContenido = null;
    if (this.getContenidoBajo() != null) {
      eContenido = this.getContenidoBajo().serializar();
    }
    return eContenido;
  }

  public Element serializarContenidoMedio(){
	  Element eContenido = null;
	  if (this.getContenidoMedio() != null) {
	      eContenido = this.getContenidoMedio().serializar();
	    }
	  return eContenido;
  }
  
  public Element serializarContenidoAlto(){
	  Element eContenido=null;
	  if (this.getContenidoAlto() != null) {
	      eContenido = this.getContenidoAlto().serializar();
	  }
	  return eContenido;
	  
  }
}
